//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Diagnostics.Contracts;
using System.IO;
using OpenLS.Spreadsheet.Formats.Biff.Tokens;

namespace OpenLS.Spreadsheet.Formats.Biff.Records
{
    internal sealed class CellParsedFormula : ParsedFormulaBase
    {
        private FormulaReadContextType _contextType;

#if DEBUG
        public byte[] GetReadBytes(FormulaReadContext context)
        {
            {
                long position = context.Reader.BaseStream.Position;
                ushort length = context.Reader.ReadUInt16();
                var result = new byte[length];
                context.Reader.Read(result, 0, result.Length);

                context.Reader.BaseStream.Position = position;
                return result;
            }
        }

        public byte[] WrittenBytes()
        {
            var memoryStream = new MemoryStream();
            var writer = new BinaryWriter(memoryStream);
            var context = new FormulaWriteContext(writer, _contextType);
            WriteCell(context);
            writer.Flush();
            long pos = memoryStream.Position;
            memoryStream.Position = 2;
            var result = new byte[pos - 2];
            memoryStream.Read(result, 0, result.Length);
            return result;
        }
#endif

        public void Read(FormulaReadContext context)
        {
#if DEBUG
            byte[] readBytes = GetReadBytes(context);
#endif
            _contextType = context.Type;
            ushort formulaLength = context.Reader.ReadUInt16();
#if BIFFDEBUG
            Debug.WriteLine(string.Format("Length = {0}", formulaLength));
            var position = context.Reader.BaseStream.Position;
            for (int i = 0; i < formulaLength; i++)
            {
                ByteHelper.ShowByte(context.Reader.BaseStream.ReadByte());
            }
            context.Reader.BaseStream.Position = position;
#endif

            Read(context, formulaLength);
#if DEBUG
            byte[] writtenBytes = WrittenBytes();
            Contract.Assert(readBytes.Length <= writtenBytes.Length);
            for (int i = 0; i < readBytes.Length; i++)
            {
                Contract.Assert(readBytes[i] == writtenBytes[i]);
            }
            ushort u = TotalTokenByteLength(context.Type);
            Contract.Assert(u == formulaLength);


#endif
        }

        public void Write(BinaryWriter writer)
        {
            WriteCell(new FormulaWriteContext(writer, _contextType));
        }

        protected override Cell GetReferenceCell(Cell cell)
        {
            return null;
        }
    }
}